Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ members = [
]

[workspace.package]
version = "0.10.8"
version = "0.10.9"
edition = "2021"
authors = ["Slice Runtime Team"]
license = "MIT OR Apache-2.0"
Expand Down
12 changes: 4 additions & 8 deletions crates/slice-cas/src/archive/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ impl CasBuilder {
let lock_path = dir.join(lock_name);
if lock_path.is_file() {
if let Ok(bytes) = std::fs::read(&lock_path) {
self.lockfile_blake3 =
Some(blake3::hash(&bytes).to_hex().to_string());
self.lockfile_blake3 = Some(blake3::hash(&bytes).to_hex().to_string());
break;
}
}
Expand All @@ -63,12 +62,9 @@ impl CasBuilder {
for section in ["dependencies", "devDependencies"] {
if let Some(obj) = val.get(section).and_then(|v| v.as_object()) {
for (name, spec_val) in obj {
let declared =
spec_val.as_str().unwrap_or("*").to_string();
let resolved_pkg = dir
.join("node_modules")
.join(name)
.join("package.json");
let declared = spec_val.as_str().unwrap_or("*").to_string();
let resolved_pkg =
dir.join("node_modules").join(name).join("package.json");
let version = std::fs::read_to_string(&resolved_pkg)
.ok()
.and_then(|s| {
Expand Down
4 changes: 3 additions & 1 deletion crates/slice-cas/src/bundler/graph_bundler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,9 @@ pub fn bundle_entrypoint_with_deps(entry_path: &Path) -> Result<String> {
bundle.push_str("var __h = null;\n");
bundle.push_str(&format!("__run = __rc[\"{}\"] = {} {{\n", rc_key, fn_kw));
bundle.push_str("if (__h && globalThis.__slice_active_http_server && typeof __slice_http_is_active === 'function' && __slice_http_is_active()) { globalThis.__slice_dispatch_fetch(__h); return; }\n");
bundle.push_str("var require = __slice_require, exports = {}, module = { exports: exports };\n");
bundle.push_str(
"var require = __slice_require, exports = {}, module = { exports: exports };\n",
);
bundle.push_str(&entry_body);
bundle.push_str("\nif (globalThis.__slice_active_http_server) __h = globalThis.__slice_active_http_server._handler;\n};\n}\n__run();\n");
} else {
Expand Down
16 changes: 6 additions & 10 deletions crates/slice-cas/src/bundler/source_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ pub fn map_bundled_error_location(bundled_js: &str, error_msg: &str) -> String {
}
if !active_short.is_empty() && b_line > marker_line_idx {
let rel_idx_0 = count_code_lines_between(&lines, marker_line_idx, b_line);
let mut resolved_line = lookup_embedded_line_map(active_line_map, rel_idx_0)
.unwrap_or(rel_idx_0 + 1);
let mut resolved_line =
lookup_embedded_line_map(active_line_map, rel_idx_0).unwrap_or(rel_idx_0 + 1);
if let Some(stmt_text) = lines.get(b_line - 1).map(|s| s.trim()) {
if !stmt_text.is_empty() {
if let Ok(orig_src) = std::fs::read_to_string(active_full) {
Expand Down Expand Up @@ -209,8 +209,8 @@ pub fn map_bundled_error_location(bundled_js: &str, error_msg: &str) -> String {
}));
if matches_line {
let rel_idx_0 = count_code_lines_between(&lines, marker_line_idx, line_1);
let mut resolved_line = lookup_embedded_line_map(active_line_map, rel_idx_0)
.unwrap_or(rel_idx_0 + 1);
let mut resolved_line =
lookup_embedded_line_map(active_line_map, rel_idx_0).unwrap_or(rel_idx_0 + 1);
if let Ok(orig_src) = std::fs::read_to_string(active_full) {
if let Some((orig_idx, _)) = orig_src.lines().enumerate().find(|(_, ol)| {
ol.contains(core_msg)
Expand Down Expand Up @@ -380,10 +380,7 @@ pub fn map_bundled_stack_trace(bundled_js: &str, raw_stack: &str) -> String {
let mut resolved: Option<(&str, usize)> = None;

if let Some(fn_name) = fn_name_opt {
let bare_fn = fn_name
.rsplit_once('.')
.map(|(_, m)| m)
.unwrap_or(fn_name);
let bare_fn = fn_name.rsplit_once('.').map(|(_, m)| m).unwrap_or(fn_name);
let fn_pat_1 = format!("function {}(", bare_fn);
let fn_pat_2 = format!("function {} (", bare_fn);
let fn_pat_3 = format!("{} = function", bare_fn);
Expand Down Expand Up @@ -438,8 +435,7 @@ pub fn map_bundled_stack_trace(bundled_js: &str, raw_stack: &str) -> String {
}
}
} else if let Some(callee) = prev_callee_fn {
let bare_callee =
callee.rsplit_once('.').map(|(_, m)| m).unwrap_or(callee);
let bare_callee = callee.rsplit_once('.').map(|(_, m)| m).unwrap_or(callee);
let call_pat = format!("{}(", bare_callee);
for l_1 in d_line_1..=fn_end_1 {
if lines[l_1 - 1].contains(&call_pat) {
Expand Down
4 changes: 2 additions & 2 deletions crates/slice-cas/src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ pub mod transpiler;
pub use pipeline_fusion::fuse_array_pipelines_ast;
pub use semantics::{analyze_typescript_semantics, source_contains_jsx, TypeDirectedHints};
pub use transpiler::{
rewrite_cjs_require, strip_js_comments, strip_typescript_and_normalize, strip_typescript_raw,
strip_typescript_raw_with_ext,
check_syntax_source, rewrite_cjs_require, strip_js_comments, strip_typescript_and_normalize,
strip_typescript_raw, strip_typescript_raw_with_ext,
};
42 changes: 42 additions & 0 deletions crates/slice-cas/src/compiler/transpiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,45 @@ pub fn rewrite_cjs_require(source: &str) -> String {
}
source.replace("require(", "__slice_cjs_require(")
}

/// Validates JS/TS/JSX/TSX syntax using Oxc's parser (`oxc::parser::Parser`).
/// Returns `Ok(())` if the source has no syntax errors, or `Err(SyntaxError message)` if invalid.
pub fn check_syntax_source(source: &str, path_hint: Option<&Path>) -> Result<(), String> {
let allocator = oxc::allocator::Allocator::default();
let parse_opts = oxc::parser::ParseOptions {
allow_return_outside_function: true,
..Default::default()
};
let is_jsx_ext = path_hint
.and_then(|p| p.extension())
.and_then(|e| e.to_str())
.is_some_and(|ext| ext.eq_ignore_ascii_case("tsx") || ext.eq_ignore_ascii_case("jsx"));
let src_type = if is_jsx_ext {
oxc::span::SourceType::tsx().with_module(true)
} else {
oxc::span::SourceType::ts().with_module(true)
};
let parsed = oxc::parser::Parser::new(&allocator, source, src_type)
.with_options(parse_opts)
.parse();
if parsed.diagnostics.is_empty() {
return Ok(());
}
if !is_jsx_ext {
let retry_tsx = oxc::parser::Parser::new(
&allocator,
source,
oxc::span::SourceType::tsx().with_module(true),
)
.with_options(parse_opts)
.parse();
if retry_tsx.diagnostics.is_empty() {
return Ok(());
}
}
let first_err = &parsed.diagnostics[0];
let file_label = path_hint
.map(|p| p.display().to_string())
.unwrap_or_else(|| "<eval>".to_string());
Err(format!("SyntaxError in {}: {}", file_label, first_err))
}
5 changes: 3 additions & 2 deletions crates/slice-cas/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ pub use bundler::{
resolve_project_entrypoint,
};
pub use compiler::{
analyze_typescript_semantics, fuse_array_pipelines_ast, strip_typescript_and_normalize,
strip_typescript_raw, strip_typescript_raw_with_ext, TypeDirectedHints,
analyze_typescript_semantics, check_syntax_source, fuse_array_pipelines_ast,
strip_typescript_and_normalize, strip_typescript_raw, strip_typescript_raw_with_ext,
TypeDirectedHints,
};
pub use linker::{has_top_level_await, wrap_top_level_await_script};

Expand Down
1 change: 0 additions & 1 deletion crates/slice-cas/src/linker/ast_walker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1376,4 +1376,3 @@ pub fn collect_live_import_reference_edits(
walk_stmt(stmt, &top_shadow, live_map, edits);
}
}

3 changes: 2 additions & 1 deletion crates/slice-cas/src/linker/builtins_and_ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ fn warn_if_declared_in_package_json_but_uninstalled(spec: &str, from_dir: &Path)
let Some(pkg_name) = bare_package_name(spec) else {
return;
};
let already_warned = WARNED_MISSING_PACKAGES.with(|w| !w.borrow_mut().insert(pkg_name.to_string()));
let already_warned =
WARNED_MISSING_PACKAGES.with(|w| !w.borrow_mut().insert(pkg_name.to_string()));
if already_warned {
return;
}
Expand Down
6 changes: 2 additions & 4 deletions crates/slice-cas/src/linker/esm_transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,10 +377,8 @@ fn try_transform_esm_to_cjs_ast(
if live_import_map.contains_key(loc_s) {
continue;
}
named_specs.push((
named.imported.name().to_string(),
loc_s.to_string(),
));
named_specs
.push((named.imported.name().to_string(), loc_s.to_string()));
}
}
}
Expand Down
15 changes: 6 additions & 9 deletions crates/slice-cas/tests/bundler_and_resolver_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,10 +452,8 @@ console.log(APP_TITLE, INTERNAL_TAG, metaUrl, metaDir, cjsDir, dynMod.lazyBanner
fn test_issues_33_and_34_class_method_source_mapping_and_cas_lockfile_provenance() {
use crate::{map_bundled_stack_trace, CasBuilder, MappedCasArchive};

let test_dir = std::env::temp_dir().join(format!(
"slice_issues_33_34_test_{}",
std::process::id()
));
let test_dir =
std::env::temp_dir().join(format!("slice_issues_33_34_test_{}", std::process::id()));
let _ = std::fs::remove_dir_all(&test_dir);
std::fs::create_dir_all(test_dir.join("src")).unwrap();
std::fs::create_dir_all(test_dir.join("node_modules/ms")).unwrap();
Expand Down Expand Up @@ -511,10 +509,8 @@ engine.processCheckout({ requestId: "ORD-99", items: [] });
.unwrap();

let bundled = bundle_entrypoint_with_deps(&entry_path).expect("bundle issue 33 app");
let mapped_err = map_bundled_error_location(
&bundled,
"Uncaught Error: Invalid checkout request: ORD-99",
);
let mapped_err =
map_bundled_error_location(&bundled, "Uncaught Error: Invalid checkout request: ORD-99");
assert!(
mapped_err.contains("(src/pricing_engine.ts:9)"),
"Dynamic error message in class method must map to src/pricing_engine.ts:9, got: {}",
Expand Down Expand Up @@ -552,7 +548,8 @@ engine.processCheckout({ requestId: "ORD-99", items: [] });
"Compacted CAS //@sm: source map must also resolve src/pricing_engine.ts:9, got: {}",
mapped_compacted_err
);
let fake_raw_stack = "Error: Invalid checkout request: ORD-99\n at processCheckout (<anonymous>:10:13)";
let fake_raw_stack =
"Error: Invalid checkout request: ORD-99\n at processCheckout (<anonymous>:10:13)";
let mapped_stack = map_bundled_stack_trace(&annotated, fake_raw_stack);
assert!(
mapped_stack.contains("src/pricing_engine.ts:"),
Expand Down
13 changes: 11 additions & 2 deletions crates/slice-cli/src/commands/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,13 @@ export default {
"#;

fn init_sveltekit_template(target_dir: &std::path::Path, project_name: &str) -> Result<()> {
std::fs::create_dir_all(target_dir.join("src").join("routes").join("api").join("items"))?;
std::fs::create_dir_all(
target_dir
.join("src")
.join("routes")
.join("api")
.join("items"),
)?;

let manifest_path = target_dir.join("slice.toml");
if !manifest_path.exists() {
Expand Down Expand Up @@ -427,7 +433,10 @@ export function handleError({ status, error }) {
std::fs::write(&hooks_path, hooks_js)?;
}

let page_srv_path = target_dir.join("src").join("routes").join("+page.server.js");
let page_srv_path = target_dir
.join("src")
.join("routes")
.join("+page.server.js");
if !page_srv_path.exists() {
let page_srv = r#"/** @type {import('./$types').PageServerLoad} */
export async function load({ url, cookies, locals }) {
Expand Down
2 changes: 1 addition & 1 deletion crates/slice-cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ pub(crate) use init::cmd_init;
pub(crate) use pack_and_compile::{
cmd_compile, cmd_info, cmd_inspect, cmd_pack, print_usage, unique_temp_cas_path,
};
pub(crate) use run::{cmd_run, run_embedded_standalone};
pub(crate) use run::{cmd_check, cmd_run, run_embedded_standalone, LAST_CLI_EXIT_CODE};
pub(crate) use test_runner::cmd_test;
Loading
Loading