aboutsummaryrefslogtreecommitdiff
path: root/src/options.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/options.zig')
-rw-r--r--src/options.zig199
1 files changed, 111 insertions, 88 deletions
diff --git a/src/options.zig b/src/options.zig
index ec3ec309a..6bb7ce941 100644
--- a/src/options.zig
+++ b/src/options.zig
@@ -611,13 +611,12 @@ pub const BundleOptions = struct {
hot_module_reloading: bool = false,
inject: ?[]string = null,
origin: string = "",
- public_dir: string = "public",
- public_dir_enabled: bool = true,
+
output_dir: string = "",
output_dir_handle: ?std.fs.Dir = null,
node_modules_bundle_url: string = "",
node_modules_bundle_pretty_path: string = "",
- public_dir_handle: ?std.fs.Dir = null,
+
write: bool = false,
preserve_symlinks: bool = false,
preserve_extensions: bool = false,
@@ -638,7 +637,7 @@ pub const BundleOptions = struct {
out_extensions: std.StringHashMap(string),
import_path_format: ImportPathFormat = ImportPathFormat.relative,
framework: ?Framework = null,
- route_config: ?RouteConfig = null,
+ routes: RouteConfig = RouteConfig.zero(),
pub fn asJavascriptBundleConfig(this: *const BundleOptions) Api.JavascriptBundleConfig {}
@@ -701,85 +700,6 @@ pub const BundleOptions = struct {
else => {},
}
- if (transform.main_fields.len > 0) {
- opts.main_fields = transform.main_fields;
- }
-
- opts.external = ExternalModules.init(allocator, &fs.fs, fs.top_level_dir, transform.external, log, opts.platform);
- opts.out_extensions = opts.platform.outExtensions(allocator);
-
- if (transform.framework) |_framework| {
- opts.framework = try Framework.fromApi(_framework);
- }
-
- if (transform.router) |route_config| {
- opts.route_config = try RouteConfig.fromApi(route_config, allocator);
- }
-
- if (transform.serve orelse false) {
- opts.preserve_extensions = true;
- opts.append_package_version_in_query_string = true;
- if (opts.origin.len == 0) {
- opts.origin = "/";
- }
-
- opts.resolve_mode = .lazy;
- var _dirs = [_]string{transform.public_dir orelse opts.public_dir};
- opts.public_dir = try fs.absAlloc(allocator, &_dirs);
- opts.public_dir_handle = std.fs.openDirAbsolute(opts.public_dir, .{ .iterate = true }) catch |err| brk: {
- var did_warn = false;
- switch (err) {
- error.FileNotFound => {
- // Be nice.
- // Check "static" since sometimes people use that instead.
- // Don't switch to it, but just tell "hey try --public-dir=static" next time
- if (transform.public_dir == null or transform.public_dir.?.len == 0) {
- _dirs[0] = "static";
- const check_static = try fs.joinAlloc(allocator, &_dirs);
- defer allocator.free(check_static);
-
- std.fs.accessAbsolute(check_static, .{}) catch {
- Output.prettyErrorln("warn: \"public\" folder missing. If there are external assets used in your project, pass --public-dir=\"public-folder-name\"", .{});
- did_warn = true;
- };
- }
-
- if (!did_warn) {
- Output.prettyErrorln("warn: \"public\" folder missing. If you want to use \"static\" as the public folder, pass --public-dir=\"static\".", .{});
- }
- opts.public_dir_enabled = false;
- },
- error.AccessDenied => {
- Output.prettyErrorln(
- "error: access denied when trying to open public_dir: \"{s}\".\nPlease re-open Speedy with access to this folder or pass a different folder via \"--public-dir\". Note: --public-dir is relative to --cwd (or the process' current working directory).\n\nThe public folder is where static assets such as images, fonts, and .html files go.",
- .{opts.public_dir},
- );
- std.process.exit(1);
- },
- else => {
- Output.prettyErrorln(
- "error: \"{s}\" when accessing public folder: \"{s}\"",
- .{ @errorName(err), opts.public_dir },
- );
- std.process.exit(1);
- },
- }
-
- break :brk null;
- };
-
- // Windows has weird locking rules for file access.
- // so it's a bad idea to keep a file handle open for a long time on Windows.
- if (isWindows and opts.public_dir_handle != null) {
- opts.public_dir_handle.?.close();
- }
- opts.hot_module_reloading = true;
- }
-
- if (opts.write and opts.output_dir.len > 0) {
- opts.output_dir_handle = try openOutputDir(opts.output_dir);
- }
-
if (!(transform.generate_node_module_bundle orelse false)) {
if (node_modules_bundle_existing) |node_mods| {
opts.node_modules_bundle = node_mods;
@@ -834,15 +754,15 @@ pub const BundleOptions = struct {
},
);
Output.flush();
- if (opts.framework == null) {
+ if (transform.framework == null) {
if (node_module_bundle.container.framework) |loaded_framework| {
opts.framework = Framework.fromLoadedFramework(loaded_framework);
}
}
- if (opts.route_config == null) {
+ if (transform.router == null) {
if (node_module_bundle.container.routes) |routes| {
- opts.route_config = RouteConfig.fromLoadedRoutes(routes);
+ opts.routes = RouteConfig.fromLoadedRoutes(routes);
}
}
} else |err| {
@@ -858,6 +778,89 @@ pub const BundleOptions = struct {
}
}
+ if (transform.main_fields.len > 0) {
+ opts.main_fields = transform.main_fields;
+ }
+
+ opts.external = ExternalModules.init(allocator, &fs.fs, fs.top_level_dir, transform.external, log, opts.platform);
+ opts.out_extensions = opts.platform.outExtensions(allocator);
+
+ if (transform.framework) |_framework| {
+ opts.framework = try Framework.fromApi(_framework);
+ }
+
+ if (transform.router) |routes| {
+ opts.routes = try RouteConfig.fromApi(routes, allocator);
+ }
+
+ if (transform.serve orelse false) {
+ opts.preserve_extensions = true;
+ opts.append_package_version_in_query_string = true;
+ if (opts.origin.len == 0) {
+ opts.origin = "/";
+ }
+
+ opts.resolve_mode = .lazy;
+
+ var dir_to_use: string = opts.routes.static_dir;
+ const static_dir_set = opts.routes.static_dir_enabled;
+
+ var _dirs = [_]string{dir_to_use};
+ opts.routes.static_dir = try fs.absAlloc(allocator, &_dirs);
+ opts.routes.static_dir_handle = std.fs.openDirAbsolute(opts.routes.static_dir, .{ .iterate = true }) catch |err| brk: {
+ var did_warn = false;
+ switch (err) {
+ error.FileNotFound => {
+ // Be nice.
+ // Check "static" since sometimes people use that instead.
+ // Don't switch to it, but just tell "hey try --public-dir=static" next time
+ if (!static_dir_set) {
+ _dirs[0] = "static";
+ const check_static = try fs.joinAlloc(allocator, &_dirs);
+ defer allocator.free(check_static);
+
+ std.fs.accessAbsolute(check_static, .{}) catch {
+ Output.prettyErrorln("warn: \"{s}\" folder missing. If there are external assets used in your project, pass --public-dir=\"public-folder-name\"", .{_dirs[0]});
+ did_warn = true;
+ };
+ }
+
+ if (!did_warn) {
+ Output.prettyErrorln("warn: \"{s}\" folder missing. If you want to use \"static\" as the public folder, pass --public-dir=\"static\".", .{_dirs[0]});
+ }
+ opts.routes.static_dir_enabled = false;
+ },
+ error.AccessDenied => {
+ Output.prettyErrorln(
+ "error: access denied when trying to open dir: \"{s}\".\nPlease re-open Speedy with access to this folder or pass a different folder via \"--public-dir\". Note: --public-dir is relative to --cwd (or the process' current working directory).\n\nThe public folder is where static assets such as images, fonts, and .html files go.",
+ .{opts.routes.static_dir},
+ );
+ std.process.exit(1);
+ },
+ else => {
+ Output.prettyErrorln(
+ "error: \"{s}\" when accessing public folder: \"{s}\"",
+ .{ @errorName(err), opts.routes.static_dir },
+ );
+ std.process.exit(1);
+ },
+ }
+
+ break :brk null;
+ };
+
+ // Windows has weird locking rules for file access.
+ // so it's a bad idea to keep a file handle open for a long time on Windows.
+ if (isWindows and opts.routes.static_dir_handle != null) {
+ opts.routes.static_dir_handle.?.close();
+ }
+ opts.hot_module_reloading = opts.platform.isWebLike();
+ }
+
+ if (opts.write and opts.output_dir.len > 0) {
+ opts.output_dir_handle = try openOutputDir(opts.output_dir);
+ }
+
return opts;
}
};
@@ -1211,7 +1214,6 @@ pub const Framework = struct {
};
pub const RouteConfig = struct {
- ///
dir: string = "",
// TODO: do we need a separate list for data-only extensions?
// e.g. /foo.json just to get the data for the route, without rendering the html
@@ -1219,17 +1221,29 @@ pub const RouteConfig = struct {
// I would consider using a custom binary format to minimize request size
// maybe like CBOR
extensions: []const string = &[_][]const string{},
+ routes_enabled: bool = false,
+
+ static_dir: string = "",
+ static_dir_handle: ?std.fs.Dir = null,
+ static_dir_enabled: bool = false,
pub fn toAPI(this: *const RouteConfig) Api.LoadedRouteConfig {
- return .{ .dir = this.dir, .extensions = this.extensions };
+ return .{
+ .dir = if (this.routes_enabled) this.dir else "",
+ .extensions = this.extensions,
+ .static_dir = if (this.static_dir_enabled) this.static_dir else "",
+ };
}
pub const DefaultDir = "pages";
+ pub const DefaultStaticDir = "public";
pub const DefaultExtensions = [_]string{ "tsx", "ts", "mjs", "jsx", "js" };
pub inline fn zero() RouteConfig {
return RouteConfig{
.dir = DefaultDir,
.extensions = std.mem.span(&DefaultExtensions),
+ .static_dir = DefaultStaticDir,
+ .routes_enabled = false,
};
}
@@ -1237,6 +1251,9 @@ pub const RouteConfig = struct {
return RouteConfig{
.extensions = loaded.extensions,
.dir = loaded.dir,
+ .static_dir = loaded.static_dir,
+ .routes_enabled = loaded.dir.len > 0,
+ .static_dir_enabled = loaded.static_dir.len > 0,
};
}
@@ -1244,9 +1261,15 @@ pub const RouteConfig = struct {
var router = zero();
var router_dir: string = std.mem.trimRight(u8, router_.dir orelse "", "/\\");
+ var static_dir: string = std.mem.trimRight(u8, router_.static_dir orelse "", "/\\");
if (router_dir.len != 0) {
router.dir = router_dir;
+ router.routes_enabled = true;
+ }
+
+ if (static_dir.len > 0) {
+ router.static_dir = static_dir;
}
if (router_.extensions.len > 0) {