tangled
alpha
login
or
join now
apoena.dev
/
sequoia
forked from
stevedylan.dev/sequoia
A CLI for publishing standard.site documents to ATProto
0
fork
atom
overview
issues
pulls
pipelines
feat: add blob images
Julien Calixte
1 day ago
702a1852
89253bee
+26
-37
1 changed file
expand all
collapse all
unified
split
packages
cli
src
commands
publish-lite.ts
+26
-37
packages/cli/src/commands/publish-lite.ts
···
36
)
37
}
38
39
-
async function resolveLocalImagePath(
40
src: string,
41
postFilePath: string,
42
contentDir: string,
43
imagesDir?: string,
44
-
): Promise<string | null> {
45
const candidates = [
46
path.resolve(path.dirname(postFilePath), src),
47
path.resolve(contentDir, src),
48
]
49
if (imagesDir) {
50
candidates.push(path.resolve(imagesDir, src))
51
-
// Try stripping a leading directory that matches imagesDir basename
52
const baseName = path.basename(imagesDir)
53
const idx = src.indexOf(baseName)
54
if (idx !== -1) {
···
56
candidates.push(path.resolve(imagesDir, after))
57
}
58
}
59
-
60
-
for (const candidate of candidates) {
61
-
try {
62
-
const stat = await fs.stat(candidate)
63
-
if (stat.isFile() && stat.size > 0) return candidate
64
-
} catch {}
65
-
}
66
-
return null
67
}
68
69
async function uploadBlob(
70
agent: Agent,
71
-
filePath: string,
72
): Promise<BlobObject | undefined> {
73
-
if (!(await fileExists(filePath))) return undefined
0
74
75
-
try {
76
-
const imageBuffer = await fs.readFile(filePath)
77
-
const mimeType = mimeTypes.lookup(filePath) || "application/octet-stream"
78
-
const response = await agent.com.atproto.repo.uploadBlob(
79
-
new Uint8Array(imageBuffer),
80
-
{ encoding: mimeType },
81
-
)
82
-
return {
83
-
$type: "blob",
84
-
ref: { $link: response.data.blob.ref.toString() },
85
-
mimeType,
86
-
size: imageBuffer.byteLength,
87
-
}
88
-
} catch (error) {
89
-
console.error(`Error uploading blob ${filePath}:`, error)
90
-
return undefined
91
}
0
92
}
93
94
async function processImages(
···
111
const src = match[2]!
112
if (!isLocalPath(src)) continue
113
114
-
const resolved = await resolveLocalImagePath(
115
-
src, postFilePath, contentDir, imagesDir,
116
-
)
117
-
if (!resolved) continue
118
-
119
-
let blob = uploadCache.get(resolved)
120
if (!blob) {
121
-
blob = await uploadBlob(agent, resolved)
0
122
if (!blob) continue
123
-
uploadCache.set(resolved, blob)
124
}
125
126
images.push({ image: blob, alt: alt || undefined })
···
36
)
37
}
38
39
+
function getImageCandidates(
40
src: string,
41
postFilePath: string,
42
contentDir: string,
43
imagesDir?: string,
44
+
): string[] {
45
const candidates = [
46
path.resolve(path.dirname(postFilePath), src),
47
path.resolve(contentDir, src),
48
]
49
if (imagesDir) {
50
candidates.push(path.resolve(imagesDir, src))
0
51
const baseName = path.basename(imagesDir)
52
const idx = src.indexOf(baseName)
53
if (idx !== -1) {
···
55
candidates.push(path.resolve(imagesDir, after))
56
}
57
}
58
+
return candidates
0
0
0
0
0
0
0
59
}
60
61
async function uploadBlob(
62
agent: Agent,
63
+
candidates: string[],
64
): Promise<BlobObject | undefined> {
65
+
for (const filePath of candidates) {
66
+
if (!(await fileExists(filePath))) continue
67
68
+
try {
69
+
const imageBuffer = await fs.readFile(filePath)
70
+
if (imageBuffer.byteLength === 0) continue
71
+
const mimeType = mimeTypes.lookup(filePath) || "application/octet-stream"
72
+
const response = await agent.com.atproto.repo.uploadBlob(
73
+
new Uint8Array(imageBuffer),
74
+
{ encoding: mimeType },
75
+
)
76
+
return {
77
+
$type: "blob",
78
+
ref: { $link: response.data.blob.ref.toString() },
79
+
mimeType,
80
+
size: imageBuffer.byteLength,
81
+
}
82
+
} catch {}
0
83
}
84
+
return undefined
85
}
86
87
async function processImages(
···
104
const src = match[2]!
105
if (!isLocalPath(src)) continue
106
107
+
let blob = uploadCache.get(src)
0
0
0
0
0
108
if (!blob) {
109
+
const candidates = getImageCandidates(src, postFilePath, contentDir, imagesDir)
110
+
blob = await uploadBlob(agent, candidates)
111
if (!blob) continue
112
+
uploadCache.set(src, blob)
113
}
114
115
images.push({ image: blob, alt: alt || undefined })