aboutsummaryrefslogtreecommitdiff
path: root/src/javascript
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-08-13 02:01:41 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-08-13 02:01:41 -0700
commitf59892f647ceef1c05e40c9cdef4f79d0a530c2f (patch)
tree6fed07dc02e722de634618a6f2d246f52510d141 /src/javascript
parent86642cbdd528bbf37708dbb30a815c9a68b6aea1 (diff)
downloadbun-f59892f647ceef1c05e40c9cdef4f79d0a530c2f.tar.gz
bun-f59892f647ceef1c05e40c9cdef4f79d0a530c2f.tar.zst
bun-f59892f647ceef1c05e40c9cdef4f79d0a530c2f.zip
late
Former-commit-id: 1d598bb05a3bac62d86063125e1fe2962f0b5cc6
Diffstat (limited to 'src/javascript')
-rw-r--r--src/javascript/jsc/api/router.zig46
-rw-r--r--src/javascript/jsc/base.zig4
-rw-r--r--src/javascript/jsc/bindings/ZigGlobalObject.cpp40
-rw-r--r--src/javascript/jsc/javascript.zig3
4 files changed, 90 insertions, 3 deletions
diff --git a/src/javascript/jsc/api/router.zig b/src/javascript/jsc/api/router.zig
index e2283e9c5..84562fee3 100644
--- a/src/javascript/jsc/api/router.zig
+++ b/src/javascript/jsc/api/router.zig
@@ -16,6 +16,7 @@ const Fs = @import("../../../fs.zig");
route: *const FilesystemRouter.Match,
query_string_map: ?QueryStringMap = null,
+param_map: ?QueryStringMap = null,
script_src: ?string = null,
script_src_buf: [1024]u8 = undefined,
@@ -223,6 +224,23 @@ pub const Instance = NewClass(
.ts = d.ts{
.@"return" = "Record<string, string | string[]>",
.tsdoc =
+ \\Route parameters & parsed query string values as a key-value object
+ \\
+ \\@example
+ \\```js
+ \\console.assert(router.query.id === "123");
+ \\console.assert(router.pathname === "/blog/posts/123");
+ \\console.assert(router.route === "blog/posts/[id]");
+ \\```
+ ,
+ },
+ },
+ .params = .{
+ .@"get" = getParams,
+ .ro = true,
+ .ts = d.ts{
+ .@"return" = "Record<string, string | string[]>",
+ .tsdoc =
\\Route parameters as a key-value object
\\
\\@example
@@ -372,6 +390,34 @@ pub fn getScriptSrc(
return js.JSValueMakeString(ctx, ZigString.init(src).toJSStringRef());
}
+pub fn getParams(
+ this: *Router,
+ ctx: js.JSContextRef,
+ thisObject: js.JSObjectRef,
+ prop: js.JSStringRef,
+ exception: js.ExceptionRef,
+) js.JSValueRef {
+ if (this.param_map == null) {
+ if (this.route.params.len > 0) {
+ if (QueryStringMap.initWithScanner(getAllocator(ctx), CombinedScanner.init(
+ "",
+ this.route.pathnameWithoutLeadingSlash(),
+ this.route.name,
+ this.route.params,
+ ))) |map| {
+ this.param_map = map;
+ } else |err| {}
+ }
+ }
+
+ // If it's still null, there are no params
+ if (this.param_map) |*map| {
+ return createQueryObject(ctx, map, exception);
+ } else {
+ return JSValue.createEmptyObject(VirtualMachine.vm.global, 0).asRef();
+ }
+}
+
pub fn getQuery(
this: *Router,
ctx: js.JSContextRef,
diff --git a/src/javascript/jsc/base.zig b/src/javascript/jsc/base.zig
index 4902c731a..e17d4c7ab 100644
--- a/src/javascript/jsc/base.zig
+++ b/src/javascript/jsc/base.zig
@@ -205,6 +205,8 @@ pub const Properties = struct {
pub const default: string = "default";
pub const include: string = "include";
+ pub const env: string = "env";
+
pub const GET = "GET";
pub const PUT = "PUT";
pub const POST = "POST";
@@ -278,6 +280,8 @@ pub const Properties = struct {
pub var navigate: js.JSStringRef = undefined;
pub var follow: js.JSStringRef = undefined;
+
+ pub const env: js.JSStringRef = undefined;
};
pub fn init() void {
diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.cpp b/src/javascript/jsc/bindings/ZigGlobalObject.cpp
index fbe3c22ae..45a68954e 100644
--- a/src/javascript/jsc/bindings/ZigGlobalObject.cpp
+++ b/src/javascript/jsc/bindings/ZigGlobalObject.cpp
@@ -121,9 +121,40 @@ void GlobalObject::setConsole(void *console) {
this->setConsoleClient(makeWeakPtr(m_console));
}
+// This is not a publicly exposed API currently.
+// This is used by the bundler to make Response, Request, FetchEvent,
+// and any other objects available globally.
void GlobalObject::installAPIGlobals(JSClassRef *globals, int count) {
WTF::Vector<GlobalPropertyInfo> extraStaticGlobals;
- extraStaticGlobals.reserveCapacity((size_t)count);
+ extraStaticGlobals.reserveCapacity((size_t)count + 1);
+
+ // This is not nearly a complete implementation. It's just enough to make some npm packages that
+ // were compiled with Webpack to run without crashing in this environment.
+ JSC::JSObject *process = JSC::constructEmptyObject(this, this->objectPrototype(), 4);
+
+ // The transpiler inlines all defined process.env vars & dead code eliminates as relevant
+ // so this is just to return undefined for any missing ones and not crash if something tries to
+ // modify it or it wasn't statically analyzable
+ JSC::JSObject *processDotEnv = JSC::constructEmptyObject(this, this->objectPrototype(), 0);
+
+ process->putDirect(this->vm(), JSC::Identifier::fromString(this->vm(), "env"), processDotEnv);
+
+ // this should be transpiled out, but just incase
+ process->putDirect(this->vm(), JSC::Identifier::fromString(this->vm(), "browser"),
+ JSC::JSValue(false));
+
+ // this gives some way of identifying at runtime whether the SSR is happening in node or not.
+ // this should probably be renamed to what the name of the bundler is, instead of "notNodeJS"
+ // but it must be something that won't evaluate to truthy in Node.js
+ process->putDirect(this->vm(), JSC::Identifier::fromString(this->vm(), "notNodeJS"),
+ JSC::JSValue(true));
+#if defined(__APPLE__)
+ process->putDirect(this->vm(), JSC::Identifier::fromString(this->vm(), "platform"),
+ JSC::jsString(this->vm(), WTF::String("darwin")));
+#else
+ process->putDirect(this->vm(), JSC::Identifier::fromString(this->vm(), "platform"),
+ JSC::jsString(this->vm(), WTF::String("linux")));
+#endif
for (int i = 0; i < count; i++) {
auto jsClass = globals[i];
@@ -137,7 +168,12 @@ void GlobalObject::installAPIGlobals(JSClassRef *globals, int count) {
GlobalPropertyInfo{JSC::Identifier::fromString(vm(), jsClass->className()),
JSC::JSValue(object), JSC::PropertyAttribute::DontDelete | 0});
}
- this->addStaticGlobals(extraStaticGlobals.data(), count);
+
+ extraStaticGlobals.uncheckedAppend(
+ GlobalPropertyInfo{JSC::Identifier::fromString(vm(), "process"), JSC::JSValue(process),
+ JSC::PropertyAttribute::DontDelete | 0});
+
+ this->addStaticGlobals(extraStaticGlobals.data(), extraStaticGlobals.size());
extraStaticGlobals.releaseBuffer();
}
diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig
index a2d9220ad..0b96ca3ed 100644
--- a/src/javascript/jsc/javascript.zig
+++ b/src/javascript/jsc/javascript.zig
@@ -117,7 +117,7 @@ pub const Wundle = struct {
prop: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSValueRef {
- if (!VirtualMachine.vm.bundler.options.routes.routes_enabled or VirtualMachine.vm.bundler.options.routes.dir.len > 0) {
+ if (!VirtualMachine.vm.bundler.options.routes.routes_enabled or VirtualMachine.vm.bundler.options.routes.dir.len == 0) {
return js.JSValueMakeUndefined(ctx);
}
@@ -238,6 +238,7 @@ pub const VirtualMachine = struct {
log: *logger.Log,
event_listeners: EventListenerMixin.Map,
main: string = "",
+ process: js.JSObjectRef = null,
pub var vm_loaded = false;
pub var vm: *VirtualMachine = undefined;