aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-10-23 04:54:17 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-10-23 04:54:17 -0700
commite039ba5130511161af5e093946e97a431b321c03 (patch)
tree492ea1e28c5508c9861629f446a283be109ab90b
parente67dd8947ba5f691f7bf6e44121170fdadfdd79f (diff)
downloadbun-e039ba5130511161af5e093946e97a431b321c03.tar.gz
bun-e039ba5130511161af5e093946e97a431b321c03.tar.zst
bun-e039ba5130511161af5e093946e97a431b321c03.zip
[Bun.js] Add `Bun.env` and support `process.env` for non-transpiled environment variables
-rw-r--r--src/javascript/jsc/javascript.zig131
1 files changed, 129 insertions, 2 deletions
diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig
index b9f34d2d3..4a6498a2b 100644
--- a/src/javascript/jsc/javascript.zig
+++ b/src/javascript/jsc/javascript.zig
@@ -30,6 +30,7 @@ const DotEnv = @import("../../env_loader.zig");
const ParseResult = @import("../../bundler.zig").ParseResult;
const PackageJSON = @import("../../resolver/package_json.zig").PackageJSON;
const MacroRemap = @import("../../resolver/package_json.zig").MacroMap;
+
pub const GlobalClasses = [_]type{
Request.Class,
Response.Class,
@@ -40,6 +41,9 @@ pub const GlobalClasses = [_]type{
Bun.Class,
Fetch.Class,
js_ast.Macro.JSNode.BunJSXCallbackFunction,
+
+ // The last item in this array becomes "process.env"
+ Bun.EnvironmentVariables.Class,
};
const Blob = @import("../../blob.zig");
@@ -554,8 +558,86 @@ pub const Bun = struct {
.get = getAssetPrefix,
.ts = d.ts{ .name = "assetPrefix", .@"return" = "string" },
},
+ .env = .{
+ .get = EnvironmentVariables.getter,
+ },
},
);
+
+ /// EnvironmentVariables is runtime defined.
+ /// Also, you can't iterate over process.env normally since it only exists at build-time otherwise
+ // This is aliased to Bun.env
+ pub const EnvironmentVariables = struct {
+ pub const Class = NewClass(
+ void,
+ .{
+ .name = "DotEnv",
+ .read_only = true,
+ },
+ .{
+ .getProperty = .{
+ .rfn = getProperty,
+ },
+ // .hasProperty = .{
+ // .rfn = hasProperty,
+ // },
+ .getPropertyNames = .{
+ .rfn = getPropertyNames,
+ },
+ },
+ .{},
+ );
+
+ pub fn getter(
+ this: void,
+ ctx: js.JSContextRef,
+ thisObject: js.JSValueRef,
+ prop: js.JSStringRef,
+ exception: js.ExceptionRef,
+ ) js.JSValueRef {
+ return js.JSObjectMake(ctx, EnvironmentVariables.Class.get().*, null);
+ }
+
+ pub fn getProperty(
+ ctx: js.JSContextRef,
+ thisObject: js.JSObjectRef,
+ propertyName: js.JSStringRef,
+ exception: js.ExceptionRef,
+ ) callconv(.C) js.JSValueRef {
+ const len = js.JSStringGetLength(propertyName);
+ var ptr = js.JSStringGetCharacters8Ptr(propertyName);
+ var name = ptr[0..len];
+ if (VirtualMachine.vm.bundler.env.map.get(name)) |value| {
+ return ZigString.toRef(value, VirtualMachine.vm.global);
+ }
+
+ return js.JSValueMakeUndefined(ctx);
+ }
+
+ pub fn hasProperty(
+ ctx: js.JSContextRef,
+ thisObject: js.JSObjectRef,
+ propertyName: js.JSStringRef,
+ ) callconv(.C) bool {
+ const len = js.JSStringGetLength(propertyName);
+ const ptr = js.JSStringGetCharacters8Ptr(propertyName);
+ const name = ptr[0..len];
+ return VirtualMachine.vm.bundler.env.map.get(name) != null;
+ }
+
+ pub fn getPropertyNames(
+ ctx: js.JSContextRef,
+ thisObject: js.JSObjectRef,
+ props: js.JSPropertyNameAccumulatorRef,
+ ) callconv(.C) void {
+ var iter = VirtualMachine.vm.bundler.env.map.iter();
+
+ while (iter.next()) |item| {
+ const str = item.key_ptr.*;
+ js.JSPropertyNameAccumulatorAddName(props, js.JSStringCreateStatic(str.ptr, str.len));
+ }
+ }
+ };
};
const bun_file_import_path = "/node_modules.server.bun";
@@ -585,6 +667,9 @@ pub const VirtualMachine = struct {
flush_list: std.ArrayList(string),
entry_point: ServerEntryPoint = undefined,
+ last_syntax_error_filename_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined,
+ last_syntax_error_filename: string = "",
+
arena: *std.heap.ArenaAllocator = undefined,
has_loaded: bool = false,
@@ -603,6 +688,15 @@ pub const VirtualMachine = struct {
pub threadlocal var vm_loaded = false;
pub threadlocal var vm: *VirtualMachine = undefined;
+ pub fn getSyntaxErrorFilename(this: *VirtualMachine) ?string {
+ if (this.last_syntax_error_filename.len > 0) {
+ const filename = this.last_syntax_error_filename;
+ this.last_syntax_error_filename = "";
+ return filename;
+ }
+
+ return null;
+ }
pub fn enableMacroMode(this: *VirtualMachine) void {
this.bundler.options.platform = .bun_macro;
this.macro_mode = true;
@@ -797,7 +891,7 @@ pub const VirtualMachine = struct {
parse_result,
@TypeOf(&source_code_printer),
&source_code_printer,
- .esm,
+ .esm_ascii,
);
if (written == 0) {
@@ -914,7 +1008,7 @@ pub const VirtualMachine = struct {
parse_result,
@TypeOf(&source_code_printer),
&source_code_printer,
- .esm,
+ .esm_ascii,
);
if (written == 0) {
@@ -1087,6 +1181,12 @@ pub const VirtualMachine = struct {
return slice;
}
+ pub fn setSyntaxErrorFilePath(global: *JSGlobalObject, loader: *JSModuleLoader, key: ZigString) void {
+ var slice = key.slice();
+ std.mem.copy(u8, &vm.last_syntax_error_filename_buf, slice);
+ vm.last_syntax_error_filename = vm.last_syntax_error_filename_buf[0..slice.len];
+ }
+
// This double prints
pub fn promiseRejectionTracker(global: *JSGlobalObject, promise: *JSPromise, rejection: JSPromiseRejectionOperation) callconv(.C) JSValue {
// VirtualMachine.vm.defaultErrorHandler(promise.result(global.vm()), null);
@@ -1630,6 +1730,33 @@ pub const VirtualMachine = struct {
}
try printStackTrace(@TypeOf(writer), writer, exception.stack, allow_ansi_color);
+
+ // SyntaxError in JavaScriptCore does not include a filename
+ // This can make debugging syntax errors difficult
+ if (this.getSyntaxErrorFilename()) |filename| {
+ const frame = ZigStackFrame{
+ .function_name = ZigString.Empty,
+ .source_url = ZigString.init(filename),
+ .position = ZigStackFramePosition.Invalid,
+ .code_type = ZigStackFrameCode.Module,
+ };
+ try writer.print(
+ comptime Output.prettyFmt(
+ "<r> <d>at <r>{any} <d>(<r>{any}<d>)<r>\n",
+ allow_ansi_color,
+ ),
+ .{
+ frame.nameFormatter(
+ allow_ansi_color,
+ ),
+ frame.sourceURLFormatter(
+ vm.bundler.fs.top_level_dir,
+ &vm.bundler.options.origin,
+ allow_ansi_color,
+ ),
+ },
+ );
+ }
}
};