mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 10:58:56 +00:00
590 lines
26 KiB
Zig
590 lines
26 KiB
Zig
pub const S3ListObjectsOptions = struct {
|
|
continuation_token: ?[]const u8,
|
|
delimiter: ?[]const u8,
|
|
encoding_type: ?[]const u8,
|
|
fetch_owner: ?bool,
|
|
max_keys: ?i64,
|
|
prefix: ?[]const u8,
|
|
start_after: ?[]const u8,
|
|
|
|
_continuation_token: ?jsc.ZigString.Slice,
|
|
_delimiter: ?jsc.ZigString.Slice,
|
|
_encoding_type: ?jsc.ZigString.Slice,
|
|
_prefix: ?jsc.ZigString.Slice,
|
|
_start_after: ?jsc.ZigString.Slice,
|
|
|
|
pub fn deinit(this: *@This()) void {
|
|
if (this._continuation_token) |slice| slice.deinit();
|
|
if (this._delimiter) |slice| slice.deinit();
|
|
if (this._encoding_type) |slice| slice.deinit();
|
|
if (this._prefix) |slice| slice.deinit();
|
|
if (this._start_after) |slice| slice.deinit();
|
|
}
|
|
};
|
|
|
|
const ObjectOwner = struct {
|
|
id: ?[]const u8,
|
|
display_name: ?[]const u8,
|
|
};
|
|
|
|
const ObjectRestoreStatus = struct {
|
|
is_restore_in_progress: ?bool,
|
|
restore_expiry_date: ?[]const u8,
|
|
};
|
|
|
|
const S3ListObjectsContents = struct {
|
|
key: []const u8,
|
|
etag: ?[]const u8,
|
|
checksum_type: ?[]const u8,
|
|
checksum_algorithme: ?[]const u8,
|
|
last_modified: ?[]const u8,
|
|
object_size: ?i64,
|
|
storage_class: ?[]const u8,
|
|
owner: ?ObjectOwner,
|
|
restore_status: ?ObjectRestoreStatus,
|
|
};
|
|
|
|
pub const S3ListObjectsV2Result = struct {
|
|
name: ?[]const u8,
|
|
prefix: ?[]const u8,
|
|
key_count: ?i64,
|
|
max_keys: ?i64,
|
|
delimiter: ?[]const u8,
|
|
encoding_type: ?[]const u8,
|
|
is_truncated: ?bool,
|
|
continuation_token: ?[]const u8,
|
|
next_continuation_token: ?[]const u8,
|
|
start_after: ?[]const u8,
|
|
common_prefixes: ?std.ArrayList([]const u8),
|
|
contents: ?std.ArrayList(S3ListObjectsContents),
|
|
|
|
pub fn deinit(this: @This()) void {
|
|
if (this.contents) |contents| {
|
|
contents.deinit();
|
|
}
|
|
if (this.common_prefixes) |common_prefixes| {
|
|
common_prefixes.deinit();
|
|
}
|
|
}
|
|
|
|
pub fn toJS(this: @This(), globalObject: *JSGlobalObject) bun.JSError!JSValue {
|
|
const jsResult = JSValue.createEmptyObject(globalObject, 12);
|
|
|
|
if (this.name) |name| {
|
|
jsResult.put(globalObject, jsc.ZigString.static("name"), try bun.String.createUTF8ForJS(globalObject, name));
|
|
}
|
|
|
|
if (this.prefix) |prefix| {
|
|
jsResult.put(globalObject, jsc.ZigString.static("prefix"), try bun.String.createUTF8ForJS(globalObject, prefix));
|
|
}
|
|
|
|
if (this.delimiter) |delimiter| {
|
|
jsResult.put(globalObject, jsc.ZigString.static("delimiter"), try bun.String.createUTF8ForJS(globalObject, delimiter));
|
|
}
|
|
|
|
if (this.start_after) |start_after| {
|
|
jsResult.put(globalObject, jsc.ZigString.static("startAfter"), try bun.String.createUTF8ForJS(globalObject, start_after));
|
|
}
|
|
if (this.encoding_type) |encoding_type| {
|
|
jsResult.put(globalObject, jsc.ZigString.static("encodingType"), try bun.String.createUTF8ForJS(globalObject, encoding_type));
|
|
}
|
|
|
|
if (this.continuation_token) |continuation_token| {
|
|
jsResult.put(globalObject, jsc.ZigString.static("continuationToken"), try bun.String.createUTF8ForJS(globalObject, continuation_token));
|
|
}
|
|
|
|
if (this.next_continuation_token) |next_continuation_token| {
|
|
jsResult.put(globalObject, jsc.ZigString.static("nextContinuationToken"), try bun.String.createUTF8ForJS(globalObject, next_continuation_token));
|
|
}
|
|
|
|
if (this.is_truncated) |is_truncated| {
|
|
jsResult.put(globalObject, jsc.ZigString.static("isTruncated"), JSValue.jsBoolean(is_truncated));
|
|
}
|
|
|
|
if (this.key_count) |key_count| {
|
|
jsResult.put(globalObject, jsc.ZigString.static("keyCount"), JSValue.jsNumber(key_count));
|
|
}
|
|
|
|
if (this.max_keys) |max_keys| {
|
|
jsResult.put(globalObject, jsc.ZigString.static("maxKeys"), JSValue.jsNumber(max_keys));
|
|
}
|
|
|
|
if (this.contents) |contents| {
|
|
const jsContents = try JSValue.createEmptyArray(globalObject, contents.items.len);
|
|
|
|
for (contents.items, 0..) |item, i| {
|
|
const objectInfo = JSValue.createEmptyObject(globalObject, 1);
|
|
objectInfo.put(globalObject, jsc.ZigString.static("key"), try bun.String.createUTF8ForJS(globalObject, item.key));
|
|
|
|
if (item.etag) |etag| {
|
|
objectInfo.put(globalObject, jsc.ZigString.static("eTag"), try bun.String.createUTF8ForJS(globalObject, etag));
|
|
}
|
|
|
|
if (item.checksum_algorithme) |checksum_algorithme| {
|
|
objectInfo.put(globalObject, jsc.ZigString.static("checksumAlgorithme"), try bun.String.createUTF8ForJS(globalObject, checksum_algorithme));
|
|
}
|
|
|
|
if (item.checksum_type) |checksum_type| {
|
|
objectInfo.put(globalObject, jsc.ZigString.static("checksumType"), try bun.String.createUTF8ForJS(globalObject, checksum_type));
|
|
}
|
|
|
|
if (item.last_modified) |last_modified| {
|
|
objectInfo.put(globalObject, jsc.ZigString.static("lastModified"), try bun.String.createUTF8ForJS(globalObject, last_modified));
|
|
}
|
|
|
|
if (item.object_size) |object_size| {
|
|
objectInfo.put(globalObject, jsc.ZigString.static("size"), JSValue.jsNumber(object_size));
|
|
}
|
|
|
|
if (item.storage_class) |storage_class| {
|
|
objectInfo.put(globalObject, jsc.ZigString.static("storageClass"), try bun.String.createUTF8ForJS(globalObject, storage_class));
|
|
}
|
|
|
|
if (item.owner) |owner| {
|
|
const jsOwner = JSValue.createEmptyObject(globalObject, 2);
|
|
if (owner.id) |id| {
|
|
jsOwner.put(globalObject, jsc.ZigString.static("id"), try bun.String.createUTF8ForJS(globalObject, id));
|
|
}
|
|
|
|
if (owner.display_name) |display_name| {
|
|
jsOwner.put(globalObject, jsc.ZigString.static("displayName"), try bun.String.createUTF8ForJS(globalObject, display_name));
|
|
}
|
|
|
|
objectInfo.put(globalObject, jsc.ZigString.static("owner"), jsOwner);
|
|
}
|
|
|
|
try jsContents.putIndex(globalObject, @intCast(i), objectInfo);
|
|
}
|
|
|
|
jsResult.put(globalObject, jsc.ZigString.static("contents"), jsContents);
|
|
}
|
|
|
|
if (this.common_prefixes) |common_prefixes| {
|
|
const jsCommonPrefixes = try JSValue.createEmptyArray(globalObject, common_prefixes.items.len);
|
|
|
|
for (common_prefixes.items, 0..) |prefix, i| {
|
|
const jsPrefix = JSValue.createEmptyObject(globalObject, 1);
|
|
jsPrefix.put(globalObject, jsc.ZigString.static("prefix"), try bun.String.createUTF8ForJS(globalObject, prefix));
|
|
try jsCommonPrefixes.putIndex(globalObject, @intCast(i), jsPrefix);
|
|
}
|
|
|
|
jsResult.put(globalObject, jsc.ZigString.static("commonPrefixes"), jsCommonPrefixes);
|
|
}
|
|
|
|
return jsResult;
|
|
}
|
|
};
|
|
|
|
pub fn parseS3ListObjectsResult(xml: []const u8) !S3ListObjectsV2Result {
|
|
var result: S3ListObjectsV2Result = .{
|
|
.contents = null,
|
|
.common_prefixes = null,
|
|
.continuation_token = null,
|
|
.delimiter = null,
|
|
.encoding_type = null,
|
|
.is_truncated = null,
|
|
.key_count = null,
|
|
.max_keys = null,
|
|
.name = null,
|
|
.next_continuation_token = null,
|
|
.prefix = null,
|
|
.start_after = null,
|
|
};
|
|
|
|
var contents = std.ArrayList(S3ListObjectsContents).init(bun.default_allocator);
|
|
var common_prefixes = std.ArrayList([]const u8).init(bun.default_allocator);
|
|
|
|
// we dont use trailing ">" as it may finish with xmlns=...
|
|
if (strings.indexOf(xml, "<ListBucketResult")) |delete_result_pos| {
|
|
var i: usize = 0;
|
|
while (i < xml[delete_result_pos..].len) {
|
|
if (xml[i] != '<') {
|
|
i += 1;
|
|
continue;
|
|
}
|
|
|
|
if (strings.indexOf(xml[i + 1 ..], ">")) |end| {
|
|
i = i + 1;
|
|
const tag_name_end_pos = i + end; // +1 for <
|
|
|
|
const tagName = xml[i..tag_name_end_pos];
|
|
i = tag_name_end_pos + 1; // +1 for >
|
|
|
|
if (strings.eql(tagName, "Contents")) {
|
|
var looking_for_end_tag = true;
|
|
|
|
var object_key: ?[]const u8 = null;
|
|
var last_modified: ?[]const u8 = null;
|
|
var object_size: ?i64 = null;
|
|
var storage_class: ?[]const u8 = null;
|
|
var etag: ?[]const u8 = null;
|
|
var checksum_type: ?[]const u8 = null;
|
|
var checksum_algorithme: ?[]const u8 = null;
|
|
var owner_id: ?[]const u8 = null;
|
|
var owner_display_name: ?[]const u8 = null;
|
|
var is_restore_in_progress: ?bool = null;
|
|
var restore_expiry_date: ?[]const u8 = null;
|
|
|
|
while (looking_for_end_tag) {
|
|
if (i >= xml.len) {
|
|
break;
|
|
}
|
|
|
|
if (xml[i] == '<') {
|
|
if (strings.indexOf(xml[i + 1 ..], ">")) |__end| {
|
|
const inner_tag_name_or_tag_end = xml[i + 1 .. i + 1 + __end];
|
|
|
|
i = i + 2 + __end;
|
|
|
|
if (strings.eql(inner_tag_name_or_tag_end, "/Contents")) {
|
|
looking_for_end_tag = false;
|
|
} else if (strings.eql(inner_tag_name_or_tag_end, "Key")) {
|
|
if (strings.indexOf(xml[i..], "</Key>")) |__tag_end| {
|
|
object_key = xml[i .. i + __tag_end];
|
|
i = i + __tag_end + 6;
|
|
}
|
|
} else if (strings.eql(inner_tag_name_or_tag_end, "LastModified")) {
|
|
if (strings.indexOf(xml[i..], "</LastModified>")) |__tag_end| {
|
|
last_modified = xml[i .. i + __tag_end];
|
|
i = i + __tag_end + 15;
|
|
}
|
|
} else if (strings.eql(inner_tag_name_or_tag_end, "Size")) {
|
|
if (strings.indexOf(xml[i..], "</Size>")) |__tag_end| {
|
|
const size = xml[i .. i + __tag_end];
|
|
|
|
object_size = std.fmt.parseInt(i64, size, 10) catch null;
|
|
i = i + __tag_end + 7;
|
|
}
|
|
} else if (strings.eql(inner_tag_name_or_tag_end, "StorageClass")) {
|
|
if (strings.indexOf(xml[i..], "</StorageClass>")) |__tag_end| {
|
|
storage_class = xml[i .. i + __tag_end];
|
|
i = i + __tag_end + 15;
|
|
}
|
|
} else if (strings.eql(inner_tag_name_or_tag_end, "ChecksumType")) {
|
|
if (strings.indexOf(xml[i..], "</ChecksumType>")) |__tag_end| {
|
|
checksum_type = xml[i .. i + __tag_end];
|
|
i = i + __tag_end + 15;
|
|
}
|
|
} else if (strings.eql(inner_tag_name_or_tag_end, "ChecksumAlgorithm")) {
|
|
if (strings.indexOf(xml[i..], "</ChecksumAlgorithm>")) |__tag_end| {
|
|
checksum_algorithme = xml[i .. i + __tag_end];
|
|
i = i + __tag_end + 20;
|
|
}
|
|
} else if (strings.eql(inner_tag_name_or_tag_end, "ETag")) {
|
|
if (strings.indexOf(xml[i..], "</ETag>")) |__tag_end| {
|
|
const input = xml[i .. i + __tag_end];
|
|
|
|
const size = std.mem.replacementSize(u8, input, """, "\"");
|
|
var output = try bun.default_allocator.alloc(u8, size);
|
|
|
|
const len = std.mem.replace(u8, input, """, "\"", output);
|
|
|
|
if (len != 0) {
|
|
etag = output[0 .. input.len - len * 5]; // 5 = """.len - 1 for replacement "
|
|
} else {
|
|
etag = input;
|
|
}
|
|
|
|
i = i + __tag_end + 7;
|
|
}
|
|
} else if (strings.eql(inner_tag_name_or_tag_end, "Owner")) {
|
|
if (strings.indexOf(xml[i..], "</Owner>")) |__tag_end| {
|
|
const owner = xml[i .. i + __tag_end];
|
|
i = i + __tag_end + 8;
|
|
|
|
if (strings.indexOf(owner, "<ID>")) |id_start| {
|
|
const id_start_pos = id_start + 4;
|
|
if (strings.indexOf(owner, "</ID>")) |id_end| {
|
|
const isNotEmpty = id_start_pos < id_end;
|
|
if (isNotEmpty) {
|
|
owner_id = owner[id_start_pos..id_end];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (strings.indexOf(owner, "<DisplayName>")) |id_start| {
|
|
const id_start_pos = id_start + 13;
|
|
if (strings.indexOf(owner, "</DisplayName>")) |id_end| {
|
|
const isNotEmpty = id_start_pos < id_end;
|
|
if (isNotEmpty) {
|
|
owner_display_name = owner[id_start_pos..id_end];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if (strings.eql(inner_tag_name_or_tag_end, "RestoreStatus")) {
|
|
if (strings.indexOf(xml[i..], "</RestoreStatus>")) |__tag_end| {
|
|
const restore_status = xml[i .. i + __tag_end];
|
|
i = i + __tag_end + 16;
|
|
|
|
if (strings.indexOf(restore_status, "<IsRestoreInProgress>")) |start| {
|
|
const start_pos = start + 21;
|
|
if (strings.indexOf(restore_status, "</IsRestoreInProgress>")) |_end| {
|
|
const isNotEmpty = start_pos < _end;
|
|
if (isNotEmpty) {
|
|
const is_restore_in_progress_string = restore_status[start_pos.._end];
|
|
|
|
if (strings.eql(is_restore_in_progress_string, "true")) {
|
|
is_restore_in_progress = true;
|
|
} else if (strings.eql(is_restore_in_progress_string, "false")) {
|
|
is_restore_in_progress = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (strings.indexOf(restore_status, "<RestoreExpiryDate>")) |start| {
|
|
const start_pos = start + 19;
|
|
if (strings.indexOf(restore_status, "</RestoreExpiryDate>")) |_end| {
|
|
const isNotEmpty = start_pos < _end;
|
|
if (isNotEmpty) {
|
|
restore_expiry_date = restore_status[start_pos.._end];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else { // char is not >
|
|
i += 1;
|
|
}
|
|
} else { // char is not <
|
|
i += 1;
|
|
}
|
|
}
|
|
|
|
if (object_key) |object_key_val| {
|
|
var owner: ?ObjectOwner = null;
|
|
|
|
if (owner_id != null or owner_display_name != null) {
|
|
owner = .{
|
|
.id = owner_id,
|
|
.display_name = owner_display_name,
|
|
};
|
|
}
|
|
|
|
var restore_status: ?ObjectRestoreStatus = null;
|
|
|
|
if (is_restore_in_progress != null or restore_expiry_date != null) {
|
|
restore_status = .{
|
|
.is_restore_in_progress = is_restore_in_progress,
|
|
.restore_expiry_date = restore_expiry_date,
|
|
};
|
|
}
|
|
|
|
try contents.append(.{
|
|
.key = object_key_val,
|
|
.etag = etag,
|
|
.checksum_type = checksum_type,
|
|
.checksum_algorithme = checksum_algorithme,
|
|
.last_modified = last_modified,
|
|
.object_size = object_size,
|
|
.storage_class = storage_class,
|
|
.owner = owner,
|
|
.restore_status = restore_status,
|
|
});
|
|
}
|
|
} else if (strings.eql(tagName, "Name")) {
|
|
if (strings.indexOf(xml[i..], "</Name>")) |_end| {
|
|
result.name = xml[i .. i + _end];
|
|
i = i + _end;
|
|
}
|
|
} else if (strings.eql(tagName, "Delimiter")) {
|
|
if (strings.indexOf(xml[i..], "</Delimiter>")) |_end| {
|
|
result.delimiter = xml[i .. i + _end];
|
|
i = i + _end;
|
|
}
|
|
} else if (strings.eql(tagName, "NextContinuationToken")) {
|
|
if (strings.indexOf(xml[i..], "</NextContinuationToken>")) |_end| {
|
|
result.next_continuation_token = xml[i .. i + _end];
|
|
i = i + _end;
|
|
}
|
|
} else if (strings.eql(tagName, "ContinuationToken")) {
|
|
if (strings.indexOf(xml[i..], "</ContinuationToken>")) |_end| {
|
|
result.continuation_token = xml[i .. i + _end];
|
|
i = i + _end;
|
|
}
|
|
} else if (strings.eql(tagName, "StartAfter")) {
|
|
if (strings.indexOf(xml[i..], "</StartAfter>")) |_end| {
|
|
result.start_after = xml[i .. i + _end];
|
|
i = i + _end;
|
|
}
|
|
} else if (strings.eql(tagName, "EncodingType")) {
|
|
if (strings.indexOf(xml[i..], "</EncodingType>")) |_end| {
|
|
result.encoding_type = xml[i .. i + _end];
|
|
i = i + _end;
|
|
}
|
|
} else if (strings.eql(tagName, "KeyCount")) {
|
|
if (strings.indexOf(xml[i..], "</KeyCount>")) |_end| {
|
|
const key_count = xml[i .. i + _end];
|
|
result.key_count = std.fmt.parseInt(i64, key_count, 10) catch null;
|
|
|
|
i = i + _end;
|
|
}
|
|
} else if (strings.eql(tagName, "MaxKeys")) {
|
|
if (strings.indexOf(xml[i..], "</MaxKeys>")) |_end| {
|
|
const max_keys = xml[i .. i + _end];
|
|
result.max_keys = std.fmt.parseInt(i64, max_keys, 10) catch null;
|
|
|
|
i = i + _end;
|
|
}
|
|
} else if (strings.eql(tagName, "Prefix")) {
|
|
if (strings.indexOf(xml[i..], "</Prefix>")) |_end| {
|
|
const prefix = xml[i .. i + _end];
|
|
|
|
if (prefix.len != 0) {
|
|
result.prefix = prefix;
|
|
}
|
|
|
|
i = i + _end;
|
|
}
|
|
} else if (strings.eql(tagName, "IsTruncated")) {
|
|
if (strings.indexOf(xml[i..], "</IsTruncated>")) |_end| {
|
|
const is_truncated = xml[i .. i + _end];
|
|
|
|
if (strings.eql(is_truncated, "true")) {
|
|
result.is_truncated = true;
|
|
} else if (strings.eql(is_truncated, "false")) {
|
|
result.is_truncated = false;
|
|
}
|
|
|
|
i = i + _end;
|
|
}
|
|
} else if (strings.eql(tagName, "CommonPrefixes")) {
|
|
if (strings.indexOf(xml[i..], "</CommonPrefixes>")) |_end| {
|
|
const common_prefixes_string = xml[i .. i + _end];
|
|
i = i + _end;
|
|
|
|
var j: usize = 0;
|
|
while (j < common_prefixes_string.len) {
|
|
if (strings.indexOf(common_prefixes_string[j..], "<Prefix>")) |start| {
|
|
j = j + start + 8;
|
|
|
|
if (strings.indexOf(common_prefixes_string[j..], "</Prefix>")) |__end| {
|
|
try common_prefixes.append(common_prefixes_string[j .. j + __end]);
|
|
j = j + __end;
|
|
}
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
i += 1;
|
|
}
|
|
}
|
|
|
|
if (contents.items.len != 0) {
|
|
result.contents = contents;
|
|
} else {
|
|
contents.deinit();
|
|
}
|
|
|
|
if (common_prefixes.items.len != 0) {
|
|
result.common_prefixes = common_prefixes;
|
|
} else {
|
|
common_prefixes.deinit();
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
pub fn getListObjectsOptionsFromJS(globalThis: *jsc.JSGlobalObject, listOptions: JSValue) !S3ListObjectsOptions {
|
|
var listObjectsOptions: S3ListObjectsOptions = .{
|
|
.continuation_token = null,
|
|
.delimiter = null,
|
|
.encoding_type = null,
|
|
.fetch_owner = null,
|
|
.max_keys = null,
|
|
.prefix = null,
|
|
.start_after = null,
|
|
|
|
._continuation_token = null,
|
|
._delimiter = null,
|
|
._encoding_type = null,
|
|
._prefix = null,
|
|
._start_after = null,
|
|
};
|
|
|
|
if (!listOptions.isObject()) {
|
|
return listObjectsOptions;
|
|
}
|
|
|
|
if (try listOptions.getTruthyComptime(globalThis, "continuationToken")) |val| {
|
|
if (val.isString()) {
|
|
const str = try bun.String.fromJS(val, globalThis);
|
|
|
|
if (str.tag != .Empty and str.tag != .Dead) {
|
|
listObjectsOptions._continuation_token = str.toUTF8(bun.default_allocator);
|
|
listObjectsOptions.continuation_token = listObjectsOptions._continuation_token.?.slice();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (try listOptions.getTruthyComptime(globalThis, "delimiter")) |val| {
|
|
if (val.isString()) {
|
|
const str = try bun.String.fromJS(val, globalThis);
|
|
|
|
if (str.tag != .Empty and str.tag != .Dead) {
|
|
listObjectsOptions._delimiter = str.toUTF8(bun.default_allocator);
|
|
listObjectsOptions.delimiter = listObjectsOptions._delimiter.?.slice();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (try listOptions.getTruthyComptime(globalThis, "encodingType")) |val| {
|
|
if (val.isString()) {
|
|
const str = try bun.String.fromJS(val, globalThis);
|
|
|
|
if (str.tag != .Empty and str.tag != .Dead) {
|
|
listObjectsOptions._encoding_type = str.toUTF8(bun.default_allocator);
|
|
listObjectsOptions.encoding_type = listObjectsOptions._encoding_type.?.slice();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (try listOptions.getBooleanLoose(globalThis, "fetchOwner")) |val| {
|
|
listObjectsOptions.fetch_owner = val;
|
|
}
|
|
|
|
if (try listOptions.getTruthyComptime(globalThis, "maxKeys")) |val| {
|
|
if (val.isNumber()) {
|
|
listObjectsOptions.max_keys = val.toInt32();
|
|
}
|
|
}
|
|
|
|
if (try listOptions.getTruthyComptime(globalThis, "prefix")) |val| {
|
|
if (val.isString()) {
|
|
const str = try bun.String.fromJS(val, globalThis);
|
|
|
|
if (str.tag != .Empty and str.tag != .Dead) {
|
|
listObjectsOptions._prefix = str.toUTF8(bun.default_allocator);
|
|
listObjectsOptions.prefix = listObjectsOptions._prefix.?.slice();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (try listOptions.getTruthyComptime(globalThis, "startAfter")) |val| {
|
|
if (val.isString()) {
|
|
const str = try bun.String.fromJS(val, globalThis);
|
|
|
|
if (str.tag != .Empty and str.tag != .Dead) {
|
|
listObjectsOptions._start_after = str.toUTF8(bun.default_allocator);
|
|
listObjectsOptions.start_after = listObjectsOptions._start_after.?.slice();
|
|
}
|
|
}
|
|
}
|
|
|
|
return listObjectsOptions;
|
|
}
|
|
|
|
const std = @import("std");
|
|
|
|
const bun = @import("bun");
|
|
const strings = bun.strings;
|
|
|
|
const jsc = bun.jsc;
|
|
const JSGlobalObject = jsc.JSGlobalObject;
|
|
const JSValue = jsc.JSValue;
|