-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhyperparamSource.ts
More file actions
87 lines (79 loc) · 2.65 KB
/
hyperparamSource.ts
File metadata and controls
87 lines (79 loc) · 2.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import type { DirSource, FileKind, FileMetadata, FileSource, SourcePart } from './types.js'
import { getFileName } from './utils.js'
export interface HyperparamFileMetadata {
key: string
eTag?: string
fileSize?: number
lastModified: string
}
function getSourceParts(sourceId: string): SourcePart[] {
const parts = sourceId.split('/')
const sourceParts = [
{ 'text': '/', 'sourceId': '' },
...parts.map((part, depth) => {
const slashSuffix = depth === parts.length - 1 ? '' : '/'
return {
text: part + slashSuffix,
sourceId: parts.slice(0, depth + 1).join('/') + slashSuffix,
}
}),
]
if (sourceParts[sourceParts.length - 1]?.text === '') {
sourceParts.pop()
}
return sourceParts
}
function getKind(sourceId: string): FileKind {
return sourceId === '' || sourceId.endsWith('/') ? 'directory' : 'file'
}
function getResolveUrl(sourceId: string, { endpoint }: {endpoint: string}): string {
const url = new URL('/api/store/get', endpoint)
url.searchParams.append('key', sourceId)
return url.toString()
}
function getPrefix(sourceId: string): string {
return sourceId.replace(/\/$/, '')
}
async function listFiles(prefix: string, { endpoint, requestInit }: {endpoint: string, requestInit?: RequestInit}): Promise<FileMetadata[]> {
const url = new URL('/api/store/list', endpoint)
url.searchParams.append('prefix', prefix)
const res = await fetch(url, requestInit)
if (res.ok) {
const files = await res.json() as HyperparamFileMetadata[]
return files.map(file => ({
name: file.key,
eTag: file.eTag,
fileSize: file.fileSize,
lastModified: file.lastModified,
sourceId: (prefix === '' ? '' : prefix + '/') + file.key,
kind: getKind(file.key),
}))
} else {
throw new Error(await res.text())
}
}
export function getHyperparamSource(sourceId: string, { endpoint, requestInit }: {endpoint: string, requestInit?: RequestInit}): FileSource | DirSource | undefined {
if (!URL.canParse(endpoint)) throw new Error('Invalid endpoint')
if (sourceId.startsWith('/')) throw new Error('Source cannot start with a /')
if (sourceId.includes('..')) throw new Error('Source cannot include ..')
const sourceParts = getSourceParts(sourceId)
if (getKind(sourceId) === 'file') {
return {
kind: 'file',
sourceId,
sourceParts,
fileName: getFileName(sourceId),
resolveUrl: getResolveUrl(sourceId, { endpoint }),
requestInit,
}
} else {
const prefix = getPrefix(sourceId)
return {
kind: 'directory',
sourceId,
sourceParts,
prefix,
listFiles: () => listFiles(prefix, { endpoint, requestInit }),
}
}
}