diff --git a/src/bun.js/api/valkey2.classes.ts b/src/bun.js/api/valkey2.classes.ts index 20abb5afe7..55ee83e9f6 100644 --- a/src/bun.js/api/valkey2.classes.ts +++ b/src/bun.js/api/valkey2.classes.ts @@ -32,7 +32,7 @@ export default [ dump: { fn: "dump" }, //duplicate: { fn: "duplicate" }, exists: { fn: "exists", length: 1 }, - //expire: { fn: "expire", length: 2 }, + expire: { fn: "expire", length: 2 }, expireat: { fn: "expireat", length: 2 }, expiretime: { fn: "expiretime" }, get: { fn: "get", length: 1 }, diff --git a/src/valkey2/command.zig b/src/valkey2/command.zig index 53dd607c0e..a84d0516a0 100644 --- a/src/valkey2/command.zig +++ b/src/valkey2/command.zig @@ -17,6 +17,7 @@ pub const CommandDescriptor = enum { DEL, DUMP, EXISTS, + EXPIRE, EXPIREAT, EXPIRETIME, GET, diff --git a/src/valkey2/js_valkey.zig b/src/valkey2/js_valkey.zig index 7d09d8efec..55691e10c5 100644 --- a/src/valkey2/js_valkey.zig +++ b/src/valkey2/js_valkey.zig @@ -761,6 +761,41 @@ pub const JsValkey = struct { return promise.toJS(); } + pub fn expire( + this: *Self, + go: *bun.jsc.JSGlobalObject, + cf: *bun.jsc.CallFrame, + ) bun.JSError!bun.jsc.JSValue { + const key = (try jsValueToJsArgument(go, cf.argument(0))) orelse { + return go.throwInvalidArgumentType("expire", "key", "string or buffer"); + }; + defer key.deinit(); + + // Validate the seconds argument as an integer in valid range + _ = try go.validateIntegerRange(cf.argument(1), i32, 0, .{ + .min = 0, + .max = 2147483647, + .field_name = "seconds", + }); + + // Convert to string argument (numbers get auto-converted by jsValueToJsArgument) + const seconds_arg = (try jsValueToJsArgument(go, cf.argument(1))) orelse { + return go.throwInvalidArgumentType("expire", "seconds", "number"); + }; + defer seconds_arg.deinit(); + + // Use the same pattern as MetFactory: call this.request() + const promise = this.request( + go, + cf.this(), + Command.initById(.EXPIRE, .{ .args = &.{ key, seconds_arg } }), + .{}, + ) catch |err| { + return protocol.valkeyErrorToJS(go, "Failed to send EXPIRE command", err); + }; + return promise.toJS(); + } + pub const getBuffer = MetFactory.@"(key: RedisKey, options)"("getBuffer", .GET, "key", .{ .return_as_buffer = true }).fxn; pub const @"type" = MetFactory.@"(key: RedisKey)"("type", .TYPE, "key").fxn; pub const append = MetFactory.@"(key: RedisKey, value: RedisValue)"("append", .APPEND, "key", "value").fxn;