diff options
author | 2021-08-13 02:01:41 -0700 | |
---|---|---|
committer | 2021-08-13 02:01:41 -0700 | |
commit | f59892f647ceef1c05e40c9cdef4f79d0a530c2f (patch) | |
tree | 6fed07dc02e722de634618a6f2d246f52510d141 /src/javascript | |
parent | 86642cbdd528bbf37708dbb30a815c9a68b6aea1 (diff) | |
download | bun-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.zig | 46 | ||||
-rw-r--r-- | src/javascript/jsc/base.zig | 4 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/ZigGlobalObject.cpp | 40 | ||||
-rw-r--r-- | src/javascript/jsc/javascript.zig | 3 |
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; |